home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / lib / bspline.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  3KB  |  153 lines

  1.  
  2. /*
  3.  *    @(#) bspline.c 9.1 93/06/14 SCOINC
  4.  */
  5. /*
  6.  *  Ported from CGI to X11 20 Apr 1993 by rr@sco.com
  7.  */
  8. /*    X11 library module to allow drawing of curves in the plane
  9.  *    utilizing the non-periodic B-spline method.
  10.  *
  11.  *    Intended to be used as follows :
  12.  *    Draw_spline(dpy,win,pix,gc,ctrl_pts,num_pts,num_steps,ord_cont)
  13.  *    where "dpy" is an open display;
  14.  *        "win" is a drawable
  15.  *        "pix" is a drawable
  16.  *        "gc" is a graphical context (GC)
  17.  *          "ctrl_pts" is an array of pointers each pointing to 
  18.  *        an array of control points in the form ctrl_pts[i,j] 
  19.  *        with i the i'th point and j the 
  20.  *        j'th coordinate (of two) in VDC units;
  21.  *          "num_pts" is the number of control points minus one.
  22.  *          "num_steps" is the number of linear pieces in the curve.
  23.  *          "ord_cont" is the desired order of continuity of the curve.
  24.  *    
  25.  *    Coded in C by Ron Record (sco!rr) Jan. 8, 1988
  26.  */
  27.  
  28. #include <X11/Xlib.h>
  29.  
  30. static double mn[2];
  31. static int K, N;
  32.  
  33. /*
  34.  * C_ord() calculates the values which are used to control the order of
  35.  * continuity of the curve.
  36.  */
  37.  
  38. C_ord(i)
  39. int i;
  40. {
  41.     int t;
  42.  
  43.     if (i < K)
  44.         t = 0;
  45.     else if (i > N)
  46.         t = N - K + 2;
  47.     else
  48.         t = i - K + 1;
  49.     return(t);
  50. }
  51.  
  52. /*
  53.  * N_blend() is the "blending function" representing the influence that
  54.  * each control point has on the curve at time u
  55.  */
  56.  
  57. double
  58. N_blend(i,k,u)
  59. int i, k;
  60. double u;
  61. {
  62.     int j;
  63.     double v;
  64.  
  65.     if (k == 1) {
  66.         v = 0;
  67.         if ((C_ord(i) <= u) && (u < C_ord(i+1)))
  68.             v = 1;
  69.     }
  70.     else {
  71.         v = 0;
  72.         j = C_ord(i+k-1) - C_ord(i);
  73.         if (j != 0)
  74.             v = (u - C_ord(i))*N_blend(i,k-1,u)/j;
  75.         j = C_ord(i+k) - C_ord(i+1);
  76.         if (j != 0)
  77.             v = v + (C_ord(i+k) - u) * N_blend(i+1,k-1,u)/j;
  78.     }
  79.     return(v);
  80. }
  81.  
  82. /*
  83.  * Compute the xy coordinates of the curve at time t
  84.  */
  85.  
  86. double *
  87. B_spline(u,n,k,p)
  88. double u;
  89. int n,k;
  90. int *p[];
  91. {
  92.     double b;
  93.     double *xy;
  94.     int i;
  95.  
  96.     xy = mn;
  97.     K = k; N = n;
  98.     xy[0] = xy[1] = 0.0;
  99.     for (i=0;i<=n;i++) {
  100.         b = N_blend(i,k,u);
  101.         xy[0] += ((double)p[i][0]*b);
  102.         xy[1] += ((double)p[i][1]*b);
  103.     }
  104.     return(xy);
  105. }
  106.  
  107. /*
  108.  * Draw_spline() is called from the application program with arguments an
  109.  * opened display, a drawable, a graphical context, an array of pointers to 
  110.  * integer coordinates specifying the control points, the number of control 
  111.  * points minus one, the number of steps for each curve, and the desired order 
  112.  * of continuity. The parameter, u, varies over the interval 
  113.  * [0,num_pts - ord_cont + 2).
  114.  */
  115.  
  116. void
  117. Draw_spline(dpy,w,p,gc,ctrl_pts,num_pts,num_steps,ord_cont)
  118. Display *dpy;
  119. Window w;
  120. Pixmap p;
  121. GC gc;
  122. int *ctrl_pts[];
  123. int num_pts,num_steps,ord_cont;
  124. {
  125.     int i;
  126.     double u;
  127.     double *coord;
  128.     XPoint points[2];
  129.  
  130.     for (i=0;i<num_steps;i++) {
  131.         u = (double)i/(double)num_steps;
  132.         u *= (double)(num_pts - ord_cont +2);    
  133.         coord = B_spline(u,num_pts,ord_cont,ctrl_pts);
  134.         if (i == 0) {
  135.             points[0].x = (int)coord[0];
  136.             points[0].y = (int)coord[1];
  137.             points[1].x = (int)coord[0];
  138.             points[1].y = (int)coord[1];
  139.         }
  140.         else {
  141.             points[0].x = points[1].x;
  142.             points[0].y = points[1].y;
  143.             points[1].x = (int)coord[0];
  144.             points[1].y = (int)coord[1];
  145.         }
  146.         if (p)
  147.             XDrawLines(dpy, p, gc, points, sizeof(points)/sizeof(points[0]),
  148.                         CoordModeOrigin);
  149.         XDrawLines(dpy, w, gc, points, sizeof(points)/sizeof(points[0]),
  150.                     CoordModeOrigin);
  151.     }
  152. }
  153.